;;; init-edit.el --- Editing settings -*- lexical-binding: t -*-
;;; Commentary:

;;; Code:

;; From: github.com/bbatsov/crux/blob/master/crux.el
;; 定义一个正则，用于标识特定模式下的字符，方便 move-begin 跳过
(defvar +edit--crux-line-start-regex-alist
  '((term-mode . "^[^#$%>\n]*[#$%>] ")
    (eshell-mode . "^[^$\n]*$ ")
    (org-mode . "^\\([*+-]\\|[0-9]+\\.\\|[[:space:]]\\)* ")
    (default . "^[[:space:]]*"))
  "Alist mapping major modes to regexps that match line prefixes to skip.")

(defun +edit--crux-move-to-mode-line-start ()
  "Move point to the first non-special character on this line.
Skips mode-specific prefixes like shell prompts or org bullets."
  (beginning-of-line)
  (let ((line-start-regex 
         (cl-loop for (mode . regex) in +edit--crux-line-start-regex-alist
                  when (or (eq mode 'default) (derived-mode-p mode))
                  return regex)))
    (when line-start-regex
      (condition-case nil
          (search-forward-regexp line-start-regex (line-end-position) t)
        (error nil)))))

(defun +edit/safe-kill-region ()
  "Only kill the region if it's actively highlighted (explicitly selected)."
  (interactive)
  (if (use-region-p)
      (call-interactively 'kill-region) ; 调用原始的 kill-region
    (message "Region not actively selected. No kill.")))

(use-package browse-kill-ring
  :ensure t
  :hook (elpaca-after-init . browse-kill-ring-default-keybindings)
  :custom
  (browse-kill-ring-resize-window '(10 . 10))
  (browse-kill-ring-display-style 'one-line)
  (browse-kill-ring-highlight-current-entry t))

(use-package easy-kill
  :ensure t
  :commands (easy-kill easy-mark))

(use-package expand-region
  :ensure t
  :commands (er/expand-region))

;; emacs 内建的 undo redo 的包装
(use-package undo-fu
  :ensure t
  :config
  ;; Increase undo history limits to reduce likelihood of data loss
  (setq undo-limit 400000           ; 400kb (default is 160kb)
        undo-strong-limit 3000000   ; 3mb   (default is 240kb)
        undo-outer-limit 48000000)) ; 48mb  (default is 24mb)

;; 像 undo-tree 一样，将 undo 信息保存到文件中
(use-package undo-fu-session
  :ensure t
  :hook (elpaca-after-init . undo-fu-session-global-mode)
  :custom
  (undo-fu-session-compression 'gz))

;; 从 undo-fu-session 保存的 undo 信息中读取数据以树状展示
(use-package vundo
  :ensure t
  :commands (vundo)
  :custom
  (vundo-glyph-alist vundo-unicode-symbols)) ; unicode 风格

;; 高亮上一次 undo/redo 的文本
(use-package volatile-highlights
  :ensure t
  :custom-face
  (vhl/default-face ((t (:background ,(face-attribute 'region :background)))))
  :hook (elpaca-after-init . volatile-highlights-mode))

;; 对文本进行过滤，选择，编辑，有多点编辑的功能，使用方式与ace-jump相似
(use-package avy
  :defer 5
  :ensure t
  :custom
  (avy-all-windows nil)                 ; 仅在当前窗口跳转文本
  (avy-background t)                    ; 跳转按键的背景
  (avy-keys '(?a ?s ?d ?f ?g ?h ?j ?l ?q ?e ?r ?u ?i ?p ?n)))

;; 多单词编辑
(use-package iedit
  :ensure t
  :commands (iedit-mode)
  :custom
  (iedit-toggle-key-default nil)) ; 取消默认快捷键绑定C-;

;; 多点编辑
(use-package multiple-cursors
  :defer 5
  :ensure t
  :config
  (setq mc/always-run-for-all t)
  (global-unset-key (kbd "M-<down-mouse-1>"))
  (global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click))

(use-package move-dup
  :ensure t
  :hook (elpaca-after-init . global-move-dup-mode))

(provide 'init-edit)
;;; init-edit.el ends here
